const ossManager = require("../utils/ossUtils");
const ImageGenerationTask = require("../models/ImageGenerationTask");

/**
 * OSS控制器
 * 处理所有OSS相关的业务逻辑
 */
class OSSController {
  /**
   * 获取所有文件夹列表
   */
  async getFolders(req, res) {
    try {
      const { prefix } = req.query;
      const result = await ossManager.getFolderList(prefix);
      res.json(result);
    } catch (error) {
      console.error("获取文件夹列表API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 创建新文件夹
   */
  async createFolder(req, res) {
    try {
      const { folderName } = req.body;

      if (!folderName || typeof folderName !== "string") {
        return res.status(400).json({
          success: false,
          error: "文件夹名称不能为空",
          code: "INVALID_FOLDER_NAME",
        });
      }

      // 验证文件夹名称
      const validNameRegex = /^[a-zA-Z0-9\u4e00-\u9fa5_-]+$/;
      if (!validNameRegex.test(folderName)) {
        return res.status(400).json({
          success: false,
          error: "文件夹名称只能包含字母、数字、中文、下划线和连字符",
          code: "INVALID_FOLDER_NAME",
        });
      }

      const result = await ossManager.createFolder(folderName);

      if (result.success) {
        res.status(201).json(result);
      } else {
        res.status(400).json(result);
      }
    } catch (error) {
      console.error("创建文件夹API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 获取指定文件夹的内容
   */
  async getFolderContents(req, res) {
    try {
      const { folderName } = req.body;
      const result = await ossManager.getFolderContents(folderName);
      res.json(result);
    } catch (error) {
      console.error("获取文件夹内容API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 上传单个文件
   */
  async uploadSingleFile(req, res) {
    try {
      const { folderName } = req.params;
      const file = req.file;

      if (!file) {
        return res.status(400).json({
          success: false,
          error: "没有上传文件",
          code: "NO_FILE_UPLOADED",
        });
      }

      const customFileName = req.body.fileName || file.originalname;

      const result = await ossManager.uploadFileToFolder(
        file.path,
        folderName,
        customFileName
      );

      if (result.success) {
        res.status(201).json({
          ...result,
          originalName: file.originalname,
          fileSize: file.size,
          fileType: this.getFileTypeFromExtension(file.originalname),
        });
      } else {
        this.cleanupTempFile(file.path);
        res.status(400).json(result);
      }
    } catch (error) {
      console.error("上传文件API错误:", error);

      if (req.file && req.file.path) {
        this.cleanupTempFile(req.file.path);
      }

      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 批量上传文件
   */
  async uploadMultipleFiles(req, res) {
    try {
      const { folderName } = req.params;
      const files = req.files;

      if (!files || files.length === 0) {
        return res.status(400).json({
          success: false,
          error: "没有上传文件",
          code: "NO_FILES_UPLOADED",
        });
      }

      const filePaths = files.map((file) => file.path);
      const result = await ossManager.uploadMultipleFiles(
        filePaths,
        folderName
      );

      // 使用箭头函数保持this上下文
      result.results = result.results.map((uploadResult, index) => ({
        ...uploadResult,
        originalName: files[index] ? files[index].originalname : "unknown",
        fileSize: files[index] ? files[index].size : 0,
        fileType: files[index]
          ? this.getFileTypeFromExtension(files[index].originalname)
          : "unknown",
      }));

      res.status(201).json(result);
    } catch (error) {
      console.error("批量上传文件API错误:", error);

      if (req.files) {
        // 使用箭头函数保持this上下文
        req.files.forEach((file) => {
          this.cleanupTempFile(file.path);
        });
      }

      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 上传base64编码的音频数据到Voice文件夹
   */
  async uploadBase64Audio(req, res) {
    try {
      const { base64Data, fileName } = req.body;

      if (!base64Data) {
        return res.status(400).json({
          success: false,
          error: "base64音频数据不能为空",
          code: "MISSING_BASE64_DATA",
        });
      }

      // 验证是否为有效的base64格式
      if (typeof base64Data !== "string") {
        return res.status(400).json({
          success: false,
          error: "base64数据必须是字符串格式",
          code: "INVALID_BASE64_FORMAT",
        });
      }

      // 验证自定义文件名（如果提供）
      if (fileName && typeof fileName !== "string") {
        return res.status(400).json({
          success: false,
          error: "文件名必须是字符串格式",
          code: "INVALID_FILENAME",
        });
      }

      // 如果提供了文件名，验证其格式
      if (fileName) {
        const validNameRegex =
          /^[a-zA-Z0-9\u4e00-\u9fa5_.-]+\.(mp3|wav|m4a|aac|ogg)$/i;
        if (!validNameRegex.test(fileName)) {
          return res.status(400).json({
            success: false,
            error:
              "文件名格式不正确，应包含有效的音频文件扩展名(.mp3, .wav, .m4a, .aac, .ogg)",
            code: "INVALID_FILENAME_FORMAT",
          });
        }
      }

      const result = await ossManager.uploadBase64Audio(base64Data, fileName);

      if (result.success) {
        // 打印URL到控制台
        console.log("=== 音频上传成功 ===");
        console.log("文件名:", result.fileName);
        console.log("OSS路径:", result.fullOssPath);
        console.log("访问URL:", result.customUrl);
        console.log("文件大小:", (result.fileSize / 1024).toFixed(2), "KB");
        if (result.duration !== null) {
          console.log("音频时长:", result.duration.toFixed(2), "秒");
        } else {
          console.log("音频时长: 无法获取");
        }
        console.log("==================");

        res.status(201).json({
          ...result,
          fileType: "audio",
        });
      } else {
        res.status(400).json(result);
      }
    } catch (error) {
      console.error("上传Base64音频API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 通过URL下载图片并上传到Images文件夹（支持webp转换和压缩）
   */
  async uploadImageFromUrl(req, res) {
    try {
      const {
        imageUrl,
        fileName,
        task_id,
        convertToWebp = true,
        quality = 85,
        width = null,
        height = null,
      } = req.body;

      if (!imageUrl) {
        return res.status(400).json({
          success: false,
          error: "图片URL不能为空",
          code: "MISSING_IMAGE_URL",
        });
      }

      // 验证URL格式
      if (typeof imageUrl !== "string") {
        return res.status(400).json({
          success: false,
          error: "图片URL必须是字符串格式",
          code: "INVALID_URL_FORMAT",
        });
      }

      // 验证自定义文件名（如果提供）
      if (fileName && typeof fileName !== "string") {
        return res.status(400).json({
          success: false,
          error: "文件名必须是字符串格式",
          code: "INVALID_FILENAME",
        });
      }

      // 如果提供了文件名，验证其格式
      if (fileName) {
        const validNameRegex =
          /^[a-zA-Z0-9\u4e00-\u9fa5_.-]+\.(jpg|jpeg|png|gif|webp|bmp)$/i;
        if (!validNameRegex.test(fileName)) {
          return res.status(400).json({
            success: false,
            error:
              "文件名格式不正确，应包含有效的图片文件扩展名(.jpg, .png, .gif, .webp, .bmp)",
            code: "INVALID_FILENAME_FORMAT",
          });
        }
      }

      // 验证task_id（如果提供）
      if (task_id && typeof task_id !== "string") {
        return res.status(400).json({
          success: false,
          error: "task_id必须是有效的字符串",
          code: "INVALID_TASK_ID",
        });
      }

      // 验证task_id是否为有效的UUID格式（如果提供）
      if (task_id) {
        const uuidRegex =
          /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
        if (!uuidRegex.test(task_id)) {
          return res.status(400).json({
            success: false,
            error: "task_id必须是有效的UUID格式",
            code: "INVALID_TASK_ID_FORMAT",
          });
        }
      }

      // 验证压缩选项
      if (typeof convertToWebp !== "boolean") {
        return res.status(400).json({
          success: false,
          error: "convertToWebp必须是布尔值",
          code: "INVALID_CONVERT_TO_WEBP",
        });
      }

      if (typeof quality !== "number" || quality < 1 || quality > 100) {
        return res.status(400).json({
          success: false,
          error: "压缩质量必须是1-100之间的数字",
          code: "INVALID_QUALITY",
        });
      }

      if (width !== null && (typeof width !== "number" || width <= 0)) {
        return res.status(400).json({
          success: false,
          error: "宽度必须是正数或null",
          code: "INVALID_WIDTH",
        });
      }

      if (height !== null && (typeof height !== "number" || height <= 0)) {
        return res.status(400).json({
          success: false,
          error: "高度必须是正数或null",
          code: "INVALID_HEIGHT",
        });
      }

      // 创建选项对象
      const options = {
        convertToWebp,
        quality,
        width,
        height,
      };

      const result = await ossManager.uploadImageFromUrl(
        imageUrl,
        fileName,
        task_id,
        options
      );

      if (result.success) {
        // 如果提供了task_id，更新数据库中对应记录的image_url字段
        if (task_id) {
          try {
            console.log(`[DEBUG] 准备更新task_id: ${task_id}`);
            
            const updateResult = await ImageGenerationTask.update(
              {
                image_url: result.customUrl,
                image_filename: result.fileName,
              },
              {
                where: { task_id: task_id },
                returning: true,
              }
            );

            if (updateResult[0] > 0) {
              console.log(
                `[SUCCESS] 已更新任务 ${task_id} 的图片URL: ${result.customUrl}`
              );
            } else {
              console.warn(`[WARNING] 未找到task_id为 ${task_id} 的任务记录，更新行数: ${updateResult[0]}`);
              
              // 只在真的找不到记录时才查询最近的任务
              const recentTasks = await ImageGenerationTask.findAll({
                limit: 5,
                order: [['created_at', 'DESC']],
                attributes: ['task_id', 'status', 'created_at']
              });
              
              console.log(`[DEBUG] 最近的5个任务记录:`, recentTasks.map(task => ({
                task_id: task.task_id,
                status: task.status,
                created_at: task.created_at
              })));
            }
          } catch (dbError) {
            console.error("[ERROR] 数据库操作失败:", dbError.message);
            // 不阻断响应，但记录错误
          }
        }

        // 打印详细信息到控制台;
        // console.log("=== 图片处理上传成功 ===");
        // console.log("原始URL:", result.originalUrl);
        // console.log("文件名:", result.fileName);
        // console.log("OSS路径:", result.fullOssPath);
        // console.log("访问URL:", result.customUrl);
        // console.log("原始大小:", (result.originalSize / 1024).toFixed(2), "KB");
        // console.log("处理后大小:", (result.fileSize / 1024).toFixed(2), "KB");
        // console.log("压缩率:", result.compressionRatio + "%");
        // console.log("文件类型:", result.contentType);
        // console.log("处理选项:", result.processOptions);
        // if (task_id) {
        //   console.log("任务ID:", task_id);
        // }
        // console.log("=======================");

        res.status(201).json({
          ...result,
          fileType: "image",
        });
      } else {
        res.status(400).json(result);
      }
    } catch (error) {
      console.error("图片URL上传API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 删除文件
   */
  async deleteFile(req, res) {
    try {
      const { ossPath } = req.body;

      if (!ossPath) {
        return res.status(400).json({
          success: false,
          error: "文件路径不能为空",
          code: "INVALID_FILE_PATH",
        });
      }

      // ossPath现在是相对于resource_AiPersion目录的路径
      const result = await ossManager.deleteFile(ossPath);
      res.json(result);
    } catch (error) {
      console.error("删除文件API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 删除文件夹
   */
  async deleteFolder(req, res) {
    try {
      const { folderName } = req.params;
      const result = await ossManager.deleteFolder(folderName);
      res.json(result);
    } catch (error) {
      console.error("删除文件夹API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 检查文件是否存在
   */
  async checkFileExists(req, res) {
    try {
      const { ossPath } = req.query;

      if (!ossPath) {
        return res.status(400).json({
          success: false,
          error: "文件路径不能为空",
          code: "INVALID_FILE_PATH",
        });
      }

      // ossPath现在是相对于resource_AiPersion目录的路径
      const exists = await ossManager.fileExists(ossPath);
      res.json({
        success: true,
        exists: exists,
        ossPath: ossPath,
      });
    } catch (error) {
      console.error("检查文件存在API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 获取文件信息
   */
  async getFileInfo(req, res) {
    try {
      const { ossPath } = req.query;

      if (!ossPath) {
        return res.status(400).json({
          success: false,
          error: "文件路径不能为空",
          code: "INVALID_FILE_PATH",
        });
      }

      // ossPath现在是相对于resource_AiPersion目录的路径
      const result = await ossManager.getFileInfo(ossPath);
      res.json(result);
    } catch (error) {
      console.error("获取文件信息API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 生成预签名URL
   */
  async generatePresignedUrl(req, res) {
    try {
      const { ossPath, expires } = req.query;

      if (!ossPath) {
        return res.status(400).json({
          success: false,
          error: "文件路径不能为空",
          code: "INVALID_FILE_PATH",
        });
      }

      // ossPath现在是相对于resource_AiPersion目录的路径
      const expiresInt = expires ? parseInt(expires) : 3600;
      const result = await ossManager.generatePresignedUrl(ossPath, expiresInt);
      res.json(result);
    } catch (error) {
      console.error("生成预签名URL API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 获取统计信息
   */
  async getStats(req, res) {
    try {
      const foldersResult = await ossManager.getFolderList();

      if (!foldersResult.success) {
        return res.status(500).json(foldersResult);
      }

      let totalFiles = 0;
      let totalSize = 0;
      const folderStats = [];

      for (const folder of foldersResult.folders) {
        try {
          const contentsResult = await ossManager.getFolderContents(
            folder.name
          );
          if (contentsResult.success) {
            const folderFileCount = contentsResult.files.length;
            const folderSize = contentsResult.files.reduce(
              (sum, file) => sum + file.size,
              0
            );

            totalFiles += folderFileCount;
            totalSize += folderSize;

            folderStats.push({
              folderName: folder.name,
              fileCount: folderFileCount,
              size: folderSize,
            });
          }
        } catch (error) {
          console.warn(
            `获取文件夹 ${folder.name} 统计信息失败:`,
            error.message
          );
        }
      }

      res.json({
        success: true,
        stats: {
          totalFolders: foldersResult.folders.length,
          totalFiles: totalFiles,
          totalSize: totalSize,
          folderStats: folderStats,
        },
        message: "获取统计信息成功",
      });
    } catch (error) {
      console.error("获取统计信息API错误:", error);
      res.status(500).json({
        success: false,
        error: error.message,
        message: "服务器内部错误",
      });
    }
  }

  /**
   * 健康检查
   */
  async healthCheck(req, res) {
    res.json({
      success: true,
      message: "OSS API服务正常",
      timestamp: new Date().toISOString(),
    });
  }

  /**
   * 根据文件扩展名获取文件类型
   */
  getFileTypeFromExtension(fileName) {
    const path = require("path");
    const ext = path.extname(fileName).toLowerCase();

    const typeMap = {
      // 图片类型
      ".jpg": "image",
      ".jpeg": "image",
      ".png": "image",
      ".gif": "image",
      ".bmp": "image",
      ".webp": "image",
      ".svg": "image",
      ".tiff": "image",
      ".ico": "image",

      // 视频类型
      ".mp4": "video",
      ".avi": "video",
      ".mov": "video",
      ".wmv": "video",
      ".flv": "video",
      ".webm": "video",
      ".mkv": "video",
      ".m4v": "video",
      ".3gp": "video",
      ".ogv": "video",

      // 音频类型
      ".mp3": "audio",
      ".wav": "audio",
      ".flac": "audio",
      ".aac": "audio",
      ".ogg": "audio",
      ".m4a": "audio",
      ".wma": "audio",
      ".opus": "audio",

      // 文档类型
      ".pdf": "document",
      ".doc": "document",
      ".docx": "document",
      ".txt": "document",
      ".rtf": "document",
      ".xls": "document",
      ".xlsx": "document",
      ".ppt": "document",
      ".pptx": "document",

      // 压缩文件
      ".zip": "archive",
      ".rar": "archive",
      ".7z": "archive",
      ".tar": "archive",
      ".gz": "archive",

      // 其他类型
      ".json": "data",
      ".xml": "data",
      ".csv": "data",
      ".html": "web",
      ".css": "web",
      ".js": "code",
      ".ts": "code",
    };

    return typeMap[ext] || "other";
  }

  /**
   * 清理临时文件的辅助方法
   */
  cleanupTempFile(filePath) {
    try {
      const fs = require("fs");
      if (fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
        console.log("临时文件已清理:", filePath);
      }
    } catch (unlinkError) {
      console.warn("删除临时文件失败:", unlinkError.message);
    }
  }
}

module.exports = new OSSController();
